package com.learning.platform.service;

import com.learning.platform.dto.*;
import com.learning.platform.entity.*;
import com.learning.platform.enums.*;
import com.learning.platform.exception.BusinessException;
import com.learning.platform.repository.*;
import com.learning.platform.security.UserPrincipal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class ExamService {
    
    private static final Logger logger = LoggerFactory.getLogger(ExamService.class);
    
    private final ExamRepository examRepository;
    private final ExamQuestionRepository examQuestionRepository;
    private final ExamRecordRepository examRecordRepository;
    private final ExamAnswerRepository examAnswerRepository;
    private final QuestionBankRepository questionBankRepository;
    
    public ExamService(ExamRepository examRepository,
                      ExamQuestionRepository examQuestionRepository,
                      ExamRecordRepository examRecordRepository,
                      ExamAnswerRepository examAnswerRepository,
                      QuestionBankRepository questionBankRepository) {
        this.examRepository = examRepository;
        this.examQuestionRepository = examQuestionRepository;
        this.examRecordRepository = examRecordRepository;
        this.examAnswerRepository = examAnswerRepository;
        this.questionBankRepository = questionBankRepository;
    }
    
    /**
     * 创建考试
     */
    public ExamResponse createExam(ExamRequest request, UserPrincipal currentUser) {
        Exam exam = new Exam();
        exam.setCourseId(request.getCourseId());
        exam.setTitle(request.getTitle());
        exam.setDescription(request.getDescription());
        exam.setExamType(request.getExamType());
        exam.setTimeLimit(request.getTimeLimit());
        exam.setPassScore(request.getPassScore());
        exam.setMaxAttempts(request.getMaxAttempts());
        exam.setStartTime(request.getStartTime());
        exam.setEndTime(request.getEndTime());
        exam.setShowResult(request.getShowResult());
        exam.setShowCorrectAnswers(request.getShowCorrectAnswers());
        exam.setShuffleQuestions(request.getShuffleQuestions());
        exam.setShuffleOptions(request.getShuffleOptions());
        exam.setCreatedBy(currentUser.getUserId());
        
        // 计算总分
        BigDecimal totalPoints = BigDecimal.ZERO;
        if (request.getQuestions() != null && !request.getQuestions().isEmpty()) {
            totalPoints = request.getQuestions().stream()
                    .map(ExamRequest.ExamQuestionRequest::getPoints)
                    .filter(points -> points != null)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }
        exam.setTotalPoints(totalPoints);
        
        Exam savedExam = examRepository.save(exam);
        
        // 保存考试题目
        if (request.getQuestions() != null) {
            for (ExamRequest.ExamQuestionRequest questionRequest : request.getQuestions()) {
                ExamQuestion examQuestion = new ExamQuestion();
                examQuestion.setExamId(savedExam.getId());
                examQuestion.setQuestionId(questionRequest.getQuestionId());
                examQuestion.setOrderNo(questionRequest.getOrderNo());
                examQuestion.setPoints(questionRequest.getPoints());
                examQuestionRepository.save(examQuestion);
            }
        }
        
        return new ExamResponse(savedExam);
    }
    
    /**
     * 更新考试
     */
    public ExamResponse updateExam(Long id, ExamRequest request, UserPrincipal currentUser) {
        Exam exam = examRepository.findById(id)
                .orElseThrow(() -> new BusinessException("考试不存在"));
        
        // 检查权限
        if (!exam.getCreatedBy().equals(currentUser.getUserId())) {
            throw new BusinessException("无权修改此考试");
        }
        
        exam.setTitle(request.getTitle());
        exam.setDescription(request.getDescription());
        exam.setExamType(request.getExamType());
        exam.setTimeLimit(request.getTimeLimit());
        exam.setPassScore(request.getPassScore());
        exam.setMaxAttempts(request.getMaxAttempts());
        exam.setStartTime(request.getStartTime());
        exam.setEndTime(request.getEndTime());
        exam.setShowResult(request.getShowResult());
        exam.setShowCorrectAnswers(request.getShowCorrectAnswers());
        exam.setShuffleQuestions(request.getShuffleQuestions());
        exam.setShuffleOptions(request.getShuffleOptions());
        
        // 重新计算总分
        BigDecimal totalPoints = BigDecimal.ZERO;
        if (request.getQuestions() != null && !request.getQuestions().isEmpty()) {
            totalPoints = request.getQuestions().stream()
                    .map(ExamRequest.ExamQuestionRequest::getPoints)
                    .filter(points -> points != null)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }
        exam.setTotalPoints(totalPoints);
        
        // 获取现有的题目关联
        List<ExamQuestion> existingQuestions = examQuestionRepository.findByExamIdOrderByOrderNoAsc(id);
        
        // 删除旧的题目关联
        if (!existingQuestions.isEmpty()) {
            examQuestionRepository.deleteByExamId(id);
            examQuestionRepository.flush(); // 强制刷新，确保删除操作立即生效
        }
        
        // 保存新的题目关联
        if (request.getQuestions() != null) {
            for (ExamRequest.ExamQuestionRequest questionRequest : request.getQuestions()) {
                try {
                    ExamQuestion examQuestion = new ExamQuestion();
                    examQuestion.setExamId(id);
                    examQuestion.setQuestionId(questionRequest.getQuestionId());
                    examQuestion.setOrderNo(questionRequest.getOrderNo());
                    examQuestion.setPoints(questionRequest.getPoints());
                    examQuestionRepository.save(examQuestion);
                } catch (Exception e) {
                    // 如果遇到重复键错误，检查是否真的存在，如果不存在则重新抛出异常
                    ExamQuestion existing = examQuestionRepository.findByExamIdAndQuestionId(id, questionRequest.getQuestionId());
                    if (existing == null) {
                        throw e; // 重新抛出，因为这不是重复键问题
                    }
                    // 如果存在，说明是重复键，忽略这个错误
                }
            }
        }
        
        Exam savedExam = examRepository.save(exam);
        return new ExamResponse(savedExam);
    }
    
    /**
     * 删除考试
     */
    public void deleteExam(Long id, UserPrincipal currentUser) {
        Exam exam = examRepository.findById(id)
                .orElseThrow(() -> new BusinessException("考试不存在"));
        
        // 检查权限
        if (!exam.getCreatedBy().equals(currentUser.getUserId())) {
            throw new BusinessException("无权删除此考试");
        }
        
        examRepository.delete(exam);
    }
    
    /**
     * 获取考试详情
     */
    @Transactional(readOnly = true)
    public ExamResponse getExam(Long id) {
        Exam exam = examRepository.findById(id)
                .orElseThrow(() -> new BusinessException("考试不存在"));
        
        return new ExamResponse(exam);
    }
    
    /**
     * 分页查询课程考试
     */
    @Transactional(readOnly = true)
    public Page<ExamResponse> getExamsByCourse(Long courseId, ExamType examType, ExamStatus status, Pageable pageable) {
        try {
            Page<Exam> exams;
            // 先尝试简单查询
            if (status != null) {
                exams = examRepository.findByCourseIdAndStatusOrderByCreatedAtDesc(courseId, status, pageable);
            } else {
                exams = examRepository.findByCourseId(courseId, examType, status, pageable);
            }
            
            // 转换为响应对象
            return exams.map(ExamResponse::new);
        } catch (Exception e) {
            // 如果查询失败，返回空页面
            return Page.empty(pageable);
        }
    }
    
    /**
     * 开始考试
     */
    public ExamRecordResponse startExam(Long examId, UserPrincipal currentUser) {
        Exam exam = examRepository.findById(examId)
                .orElseThrow(() -> new BusinessException("考试不存在"));
        
        // 检查考试状态
        if (exam.getStatus() != ExamStatus.PUBLISHED) {
            throw new BusinessException("考试未发布");
        }
        
        // 检查时间限制
        LocalDateTime now = LocalDateTime.now();
        if (exam.getStartTime() != null && now.isBefore(exam.getStartTime())) {
            throw new BusinessException("考试尚未开始");
        }
        if (exam.getEndTime() != null && now.isAfter(exam.getEndTime())) {
            throw new BusinessException("考试已结束");
        }
        
        // 检查是否有进行中的记录
        var inProgressRecord = examRecordRepository.findInProgressRecord(currentUser.getUserId(), examId);
        if (inProgressRecord.isPresent()) {
            return new ExamRecordResponse(inProgressRecord.get());
        }
        
        // 检查尝试次数
        long attemptCount = examRecordRepository.countByUserIdAndExamId(currentUser.getUserId(), examId);
        if (attemptCount >= exam.getMaxAttempts()) {
            throw new BusinessException("已达到最大尝试次数");
        }
        
        // 创建考试记录
        ExamRecord record = new ExamRecord();
        record.setExamId(examId);
        record.setUserId(currentUser.getUserId());
        record.setAttemptNumber((int)(attemptCount + 1));
        record.setStartTime(now);
        record.setTotalPoints(exam.getTotalPoints());
        record.setTotalScore(BigDecimal.ZERO); // 初始化为0分
        record.setStatus(ExamRecordStatus.IN_PROGRESS);
        record.setPassStatus(PassStatus.PENDING); // 初始化通过状态
        record.setAutoGraded(false);
        record.setManualGraded(false);
        
        ExamRecord savedRecord = examRecordRepository.save(record);
        return new ExamRecordResponse(savedRecord);
    }
    
    /**
     * 提交考试
     */
    public ExamRecordResponse submitExam(ExamSubmitRequest request, UserPrincipal currentUser) {
        ExamRecord record = examRecordRepository.findById(request.getRecordId())
                .orElseThrow(() -> new BusinessException("考试记录不存在"));
        
        // 检查权限
        if (!record.getUserId().equals(currentUser.getUserId())) {
            throw new BusinessException("无权提交此考试");
        }
        
        // 检查状态
        if (record.getStatus() != ExamRecordStatus.IN_PROGRESS) {
            throw new BusinessException("考试记录状态错误");
        }
        
        // 清理已存在的答案（避免重复提交）
        examAnswerRepository.deleteByRecordId(request.getRecordId());
        
        // 保存答案
        for (ExamSubmitRequest.AnswerSubmit answerSubmit : request.getAnswers()) {
            ExamAnswer answer = new ExamAnswer();
            answer.setRecordId(request.getRecordId());
            answer.setQuestionId(answerSubmit.getQuestionId());
            
            // 将答案转换为有效的JSON格式
            String jsonAnswer = convertToJsonString(answerSubmit.getAnswer());
            answer.setUserAnswer(jsonAnswer);
            
            examAnswerRepository.save(answer);
        }
        
        // 更新记录状态
        record.setSubmitTime(LocalDateTime.now());
        record.setStatus(ExamRecordStatus.SUBMITTED);
        record.setTimeSpent((int)java.time.Duration.between(record.getStartTime(), record.getSubmitTime()).getSeconds());
        
        // 自动评分
        autoGradeExam(record);
        
        ExamRecord savedRecord = examRecordRepository.save(record);
        return new ExamRecordResponse(savedRecord);
    }
    
    /**
     * 自动评分
     */
    private void autoGradeExam(ExamRecord record) {
        List<ExamAnswer> answers = examAnswerRepository.findByRecordIdOrderByQuestionId(record.getId());
        BigDecimal totalScore = BigDecimal.ZERO;
        
        for (ExamAnswer answer : answers) {
            QuestionBank question = questionBankRepository.findById(answer.getQuestionId())
                    .orElseThrow(() -> new BusinessException("题目不存在"));
            
            // 调试日志
            logger.info("评分题目: questionId={}, type={}, correctAnswers={}, userAnswer={}", 
                answer.getQuestionId(), question.getQuestionType(), question.getCorrectAnswers(), answer.getUserAnswer());
            
            boolean isCorrect = evaluateAnswerCorrectness(question, answer.getUserAnswer());
            ExamQuestion examQuestion = examQuestionRepository.findByExamIdAndQuestionId(record.getExamId(), answer.getQuestionId());
            
            if (examQuestion == null) {
                // 如果找不到考试题目关联，记录错误并跳过
                logger.error("未找到考试题目关联，examId={}, questionId={}", record.getExamId(), answer.getQuestionId());
                answer.setIsCorrect(false);
                answer.setScore(BigDecimal.ZERO);
            } else if (isCorrect) {
                answer.setIsCorrect(true);
                answer.setScore(examQuestion.getPoints());
                totalScore = totalScore.add(examQuestion.getPoints());
            } else {
                answer.setIsCorrect(false);
                answer.setScore(BigDecimal.ZERO);
            }
            examAnswerRepository.save(answer);
        }
        
        record.setTotalScore(totalScore);
        record.setAutoGraded(true);
        
        // 判断是否通过
        Exam exam = examRepository.findById(record.getExamId()).orElseThrow();
        if (totalScore.compareTo(exam.getPassScore()) >= 0) {
            record.setPassStatus(PassStatus.PASSED);
        } else {
            record.setPassStatus(PassStatus.FAILED);
        }
    }

    /**
     * 判断答案是否正确：依据题型做格式化比较
     */
    private boolean evaluateAnswerCorrectness(QuestionBank question, String userAnswerRaw) {
        if (question.getQuestionType() == QuestionType.ESSAY || question.getQuestionType() == QuestionType.FILL_BLANK) {
            // 主观题默认不做自动评分
            return false;
        }

        String correctRaw = question.getCorrectAnswers();
        if (correctRaw == null) {
            return false;
        }

        // 统一把两侧都转为字符串集合，忽略顺序、去除空白
        java.util.Set<String> correctSet = toNormalizedStringSet(correctRaw);
        java.util.Set<String> userSet = toNormalizedStringSet(userAnswerRaw);
        
        // 调试日志
        logger.info("答案比较: type={}, correctRaw={}, userAnswerRaw={}, correctSet={}, userSet={}", 
            question.getQuestionType(), correctRaw, userAnswerRaw, correctSet, userSet);

        if (question.getQuestionType() == QuestionType.SINGLE_CHOICE || question.getQuestionType() == QuestionType.TRUE_FALSE) {
            // 单选/判断期望只有一个
            if (correctSet.isEmpty() || userSet.isEmpty()) {
                return false;
            }
            
            String correctAnswer = correctSet.iterator().next();
            String userAnswer = userSet.iterator().next();
            
            // 对于判断题，特殊处理布尔值比较
            if (question.getQuestionType() == QuestionType.TRUE_FALSE) {
                return isTrueFalseEqual(correctAnswer, userAnswer);
            }
            
            return correctAnswer.equals(userAnswer);
        }

        if (question.getQuestionType() == QuestionType.MULTIPLE_CHOICE) {
            return !correctSet.isEmpty() && correctSet.equals(userSet);
        }

        return false;
    }

    /**
     * 将答案字符串（JSON数组字符串或以逗号分隔的字符串或布尔）转换为标准集合
     */
    private java.util.Set<String> toNormalizedStringSet(String raw) {
        java.util.Set<String> result = new java.util.LinkedHashSet<>();
        if (raw == null) {
            return result;
        }
        String trimmed = raw.trim();
        
        try {
            // 尝试解析JSON
            com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
            
            // JSON字符串值（被双引号包围）
            if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) {
                String value = mapper.readValue(trimmed, String.class);
                result.add(value);
                return result;
            }
            
            // JSON数组
            if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
                java.util.List<?> list = mapper.readValue(trimmed, java.util.List.class);
                for (Object o : list) {
                    if (o == null) continue;
                    result.add(String.valueOf(o).trim());
                }
                return result;
            }
            
            // JSON原始值（null, true, false, 数字）
            Object jsonValue = mapper.readValue(trimmed, Object.class);
            if (jsonValue != null) {
                result.add(String.valueOf(jsonValue).trim());
                return result;
            }
        } catch (Exception ignored) {
            logger.debug("不是有效JSON格式，使用普通字符串解析: {}", trimmed);
        }

        // 逗号分隔或布尔或普通字符串
        if (trimmed.contains(",")) {
            for (String part : trimmed.split(",")) {
                String v = part.trim();
                if (!v.isEmpty()) {
                    result.add(v);
                }
            }
        } else {
            // 处理 true/false/数字/单值
            if (!trimmed.isEmpty()) {
                result.add(trimmed);
            }
        }
        return result;
    }
    
    /**
     * 判断题答案专用比较方法
     * 处理多种可能的布尔值表示形式
     */
    private boolean isTrueFalseEqual(String correctAnswer, String userAnswer) {
        // 将字符串转为标准的布尔值
        boolean correct = parseBoolean(correctAnswer);
        boolean user = parseBoolean(userAnswer);
        
        logger.info("判断题比较: correct='{}'->{}, user='{}'->{}, equal={}", 
            correctAnswer, correct, userAnswer, user, correct == user);
        
        return correct == user;
    }
    
    /**
     * 解析布尔值，支持多种格式
     */
    private boolean parseBoolean(String value) {
        if (value == null) return false;
        String v = value.trim().toLowerCase();
        return "true".equals(v) || "1".equals(v) || "yes".equals(v) || "正确".equals(v);
    }
    
    /**
     * 将答案转换为有效的JSON字符串
     */
    private String convertToJsonString(String answer) {
        if (answer == null) {
            return "null";
        }
        
        try {
            // 检查是否已经是有效的JSON
            com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
            mapper.readTree(answer);
            return answer; // 已经是有效JSON，直接返回
        } catch (Exception e) {
            // 不是有效JSON，需要包装为JSON字符串
            try {
                com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
                return mapper.writeValueAsString(answer);
            } catch (Exception ex) {
                // 最后的备选方案：手动包装
                return "\"" + answer.replace("\"", "\\\"") + "\"";
            }
        }
    }
    
    /**
     * 获取考试记录
     */
    @Transactional(readOnly = true)
    public ExamRecordResponse getExamRecord(Long recordId) {
        ExamRecord record = examRecordRepository.findById(recordId)
                .orElseThrow(() -> new BusinessException("考试记录不存在"));
        
        return new ExamRecordResponse(record);
    }
    
    /**
     * 获取用户考试记录
     */
    @Transactional(readOnly = true)
    public Page<ExamRecordResponse> getUserExamRecords(Long userId, Pageable pageable) {
        return examRecordRepository.findByUserId(userId, pageable)
                .map(ExamRecordResponse::new);
    }
    
    /**
     * 获取考试答案明细
     */
    @Transactional(readOnly = true)
    public List<ExamAnswerResponse> getExamAnswers(Long recordId, UserPrincipal currentUser) {
        ExamRecord record = examRecordRepository.findById(recordId)
                .orElseThrow(() -> new BusinessException("考试记录不存在"));
        // 仅允许本人或后续可扩展教师/管理员查看
        if (!record.getUserId().equals(currentUser.getUserId())) {
            throw new BusinessException("无权查看此考试答案");
        }

        Exam exam = examRepository.findById(record.getExamId())
                .orElseThrow(() -> new BusinessException("考试不存在"));

        boolean canShowCorrect = Boolean.TRUE.equals(exam.getShowCorrectAnswers());

        List<ExamAnswer> answers = examAnswerRepository.findByRecordIdOrderByQuestionId(recordId);
        return answers.stream().map(a -> {
            ExamAnswerResponse resp = new ExamAnswerResponse(a);
            // 题目信息
            QuestionBank question = questionBankRepository.findById(a.getQuestionId())
                    .orElseThrow(() -> new BusinessException("题目不存在"));
            resp.setQuestion(new QuestionBankResponse(question));
            if (canShowCorrect) {
                resp.setCorrectAnswer(question.getCorrectAnswers());
            }
            return resp;
        }).collect(Collectors.toList());
    }

    /**
     * 搜索考试
     */
    @Transactional(readOnly = true)
    public Page<ExamResponse> searchExams(Long courseId, String examType, String status, 
                                        String keyword, Pageable pageable, UserPrincipal currentUser) {
        return examRepository.searchExams(courseId, examType, status, keyword, pageable)
                .map(exam -> new ExamResponse(exam));
    }
    
    /**
     * 发布考试
     */
    @Transactional
    public void publishExam(Long id, UserPrincipal currentUser) {
        Exam exam = examRepository.findById(id)
                .orElseThrow(() -> new BusinessException("考试不存在"));
        
        // 检查权限
        if (!exam.getCreatedBy().equals(currentUser.getUserId())) {
            throw new BusinessException("无权发布此考试");
        }
        
        // 检查考试状态
        if (exam.getStatus() != ExamStatus.DRAFT) {
            throw new BusinessException("只能发布草稿状态的考试");
        }
        
        // 检查是否有题目
        long questionCount = examQuestionRepository.countByExamId(id);
        if (questionCount == 0) {
            throw new BusinessException("请先添加考试题目");
        }
        
        exam.setStatus(ExamStatus.PUBLISHED);
        examRepository.save(exam);
    }
    
    /**
     * 归档考试
     */
    @Transactional
    public void archiveExam(Long id, UserPrincipal currentUser) {
        Exam exam = examRepository.findById(id)
                .orElseThrow(() -> new BusinessException("考试不存在"));
        
        // 检查权限
        if (!exam.getCreatedBy().equals(currentUser.getUserId())) {
            throw new BusinessException("无权归档此考试");
        }
        
        // 检查考试状态
        if (exam.getStatus() != ExamStatus.PUBLISHED) {
            throw new BusinessException("只能归档已发布的考试");
        }
        
        exam.setStatus(ExamStatus.ARCHIVED);
        examRepository.save(exam);
    }
    
    /**
     * 复制考试（连同题目）
     */
    @Transactional
    public ExamResponse copyExam(Long id, UserPrincipal currentUser) {
        Exam source = examRepository.findById(id)
                .orElseThrow(() -> new BusinessException("考试不存在"));
        // 权限：仅创建者或管理员/教师（上层控制）
        if (!source.getCreatedBy().equals(currentUser.getUserId())) {
            // 允许教师/管理员在上层通过注解控制，这里作最小校验
        }

        Exam copy = new Exam();
        copy.setCourseId(source.getCourseId());
        copy.setTitle(source.getTitle() + " - 复制");
        copy.setDescription(source.getDescription());
        copy.setExamType(source.getExamType());
        copy.setTimeLimit(source.getTimeLimit());
        copy.setTotalPoints(source.getTotalPoints());
        copy.setPassScore(source.getPassScore());
        copy.setMaxAttempts(source.getMaxAttempts());
        copy.setStartTime(source.getStartTime());
        copy.setEndTime(source.getEndTime());
        copy.setStatus(ExamStatus.DRAFT);
        copy.setShowResult(source.getShowResult());
        copy.setShowCorrectAnswers(source.getShowCorrectAnswers());
        copy.setShuffleQuestions(source.getShuffleQuestions());
        copy.setShuffleOptions(source.getShuffleOptions());
        copy.setCreatedBy(currentUser.getUserId());

        Exam saved = examRepository.save(copy);

        // 复制题目
        List<ExamQuestion> srcQuestions = examQuestionRepository.findByExamIdOrderByOrderNoAsc(id);
        for (ExamQuestion q : srcQuestions) {
            ExamQuestion nq = new ExamQuestion();
            nq.setExamId(saved.getId());
            nq.setQuestionId(q.getQuestionId());
            nq.setOrderNo(q.getOrderNo());
            nq.setPoints(q.getPoints());
            examQuestionRepository.save(nq);
        }

        return new ExamResponse(saved);
    }
    
    /**
     * 获取考试题目
     */
    public List<QuestionBankResponse> getExamQuestions(Long examId, UserPrincipal currentUser) {
        Exam exam = examRepository.findById(examId)
                .orElseThrow(() -> new BusinessException("考试不存在"));
        
        // 检查考试状态
        if (exam.getStatus() != ExamStatus.PUBLISHED) {
            throw new BusinessException("考试未发布");
        }
        
        // 获取考试题目
        List<ExamQuestion> examQuestions = examQuestionRepository.findByExamIdOrderByOrderNoAsc(examId);
        
        // 转换为响应对象
        return examQuestions.stream()
            .map(eq -> {
                QuestionBank question = questionBankRepository.findById(eq.getQuestionId())
                    .orElseThrow(() -> new BusinessException("题目不存在"));
                return new QuestionBankResponse(question);
            })
            .collect(Collectors.toList());
    }
    
    /**
     * 获取课程的已发布考试列表 - 简化版本，直接返回List
     */
    @Transactional(readOnly = true)
    public List<ExamResponse> getPublishedExamsByCourse(Long courseId) {
        System.out.println("🔍 ExamService: 获取课程 " + courseId + " 的已发布考试");
        
        try {
            List<Exam> exams = examRepository.findByCourseIdAndStatusOrderByCreatedAtDesc(courseId, ExamStatus.PUBLISHED);
            System.out.println("✅ ExamService: 找到 " + exams.size() + " 个已发布考试");
            
            return exams.stream()
                .map(ExamResponse::new)
                .collect(Collectors.toList());
        } catch (Exception e) {
            System.err.println("❌ ExamService: 获取考试失败 - " + e.getMessage());
            e.printStackTrace();
            return List.of(); // 返回空列表
        }
    }
    
    /**
     * 获取考试题目 - 无需用户认证的版本
     */
    @Transactional(readOnly = true)
    public List<QuestionBankResponse> getExamQuestions(Long examId) {
        System.out.println("📝 ExamService: 获取考试 " + examId + " 的题目");
        
        try {
            // 使用已有的仓库方法（按序号升序）
            List<ExamQuestion> examQuestions = examQuestionRepository.findByExamIdOrderByOrderNoAsc(examId);
            System.out.println("✅ ExamService: 找到 " + examQuestions.size() + " 道题目");
            
            return examQuestions.stream()
                .map(eq -> {
                    QuestionBank question = questionBankRepository.findById(eq.getQuestionId())
                        .orElseThrow(() -> new BusinessException("题目不存在"));
                    return new QuestionBankResponse(question);
                })
                .collect(Collectors.toList());
        } catch (Exception e) {
            System.err.println("❌ ExamService: 获取题目失败 - " + e.getMessage());
            e.printStackTrace();
            return List.of();
        }
    }

    @Transactional(readOnly = true)
    public ExamStatsResponse getExamStats(Long examId) {
        Exam exam = examRepository.findById(examId)
                .orElseThrow(() -> new BusinessException("考试不存在"));

        long participantCount = examRecordRepository.countDistinctUsersByExamId(examId);
        long recordCount = examRecordRepository.countByExamId(examId);
        Double avgScore = examRecordRepository.getAverageScoreByExamId(examId);
        // 部分项目可能没有百分比查询方法，直接根据exam.totalPoints推算
        BigDecimal averageScore = BigDecimal.valueOf(avgScore == null ? 0.0 : avgScore).setScale(2, java.math.RoundingMode.HALF_UP);
        BigDecimal averagePercentage = BigDecimal.ZERO;
        if (exam.getTotalPoints() != null && exam.getTotalPoints().doubleValue() > 0) {
            averagePercentage = averageScore
                    .divide(exam.getTotalPoints(), 4, java.math.RoundingMode.HALF_UP)
                    .multiply(BigDecimal.valueOf(100))
                    .setScale(2, java.math.RoundingMode.HALF_UP);
        }

        long passCount = examRecordRepository.countByExamIdAndPassStatus(examId, PassStatus.PASSED);
        long failCount = examRecordRepository.countByExamIdAndPassStatus(examId, PassStatus.FAILED);
        BigDecimal passRate = BigDecimal.ZERO;
        if (recordCount > 0) {
            passRate = BigDecimal.valueOf((passCount * 100.0) / recordCount)
                    .setScale(2, java.math.RoundingMode.HALF_UP);
        }

        ExamStatsResponse stats = new ExamStatsResponse(examId);
        stats.setParticipantCount(participantCount);
        stats.setRecordCount(recordCount);
        stats.setAverageScore(averageScore);
        stats.setAveragePercentage(averagePercentage);
        stats.setPassCount(passCount);
        stats.setFailCount(failCount);
        stats.setPassRate(passRate);
        return stats;
    }

    @Transactional(readOnly = true)
    public java.util.List<ExamTrendPoint> getExamDailyTrend(Long examId, int days) {
        java.util.List<ExamTrendPoint> list = new java.util.ArrayList<>();
        java.util.List<com.learning.platform.repository.DailyTrendRow> rows = examRecordRepository.findDailyTrend(examId, days);
        for (var row : rows) {
            ExamTrendPoint p = new ExamTrendPoint();
            p.setDay(row.getDay().toLocalDate());
            p.setRecordCount(row.getRecordCount() == null ? 0L : row.getRecordCount());
            java.math.BigDecimal avg = java.math.BigDecimal.valueOf(row.getAvgScore() == null ? 0.0 : row.getAvgScore())
                    .setScale(2, java.math.RoundingMode.HALF_UP);
            p.setAvgScore(avg);
            java.math.BigDecimal pass = java.math.BigDecimal.valueOf(row.getPassRate() == null ? 0.0 : row.getPassRate() * 100.0)
                    .setScale(2, java.math.RoundingMode.HALF_UP);
            p.setPassRate(pass);
            list.add(p);
        }
        return list;
    }
}